package yl.hs.bmipfull.service.system.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.daos.system.ICoreDataTagDao;
import yl.hs.bmipfull.daos.system.IOrganizationInfoDao;
import yl.hs.bmipfull.daos.system.IUserInfoDao;
import yl.hs.bmipfull.pojo.system.OrganizationInfoEntity;
import yl.hs.bmipfull.service.system.IOrganizationInfoService;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.HanYuHelper;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.utils.datastate.OrganizationUnitType;
import yl.hs.bmipfull.viewmodels.PageQuery;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 作用:  组织架构信息服务层接口实现<br/>
 * 创建时间: 2021年05月12日 11时47分31秒 <br/>
 *
 * @author 张凯
 */
@Service
public class OrganizationInfoServiceImpl extends SystemBaseService implements IOrganizationInfoService {


    @Autowired
    IOrganizationInfoDao dao;
    @Autowired
    ICoreDataTagDao tagDao;

    @Autowired
    IUserInfoDao userInfoDao;

    @Override
    public List<OrganizationInfoEntity> queryList(PageQuery pageQuery) throws Exception {
        pageQuery.checkSortSides(OrganizationInfoEntity.class);
        return dao.queryList(pageQuery.getQuery());
    }

    public List<OrganizationInfoEntity> queryListByFullNameKey(String key) {
        var list = dao.queryListByFullNameKey(key);
        return (List<OrganizationInfoEntity>) Tl.toTreeSelect(list, null);
    }

    @Override
    public List<Map<String, Object>> queryTreeList(PageQuery pageQuery) {
        pageQuery.checkSortSides(OrganizationInfoEntity.class);
        var findList = dao.queryList(pageQuery.getQuery());
        if (findList.size() > 0) {
            List<String> snList = new ArrayList<>();
            findList.forEach(t -> {
                var snArray = t.getParentCode().split(",");
                for (var sn : snArray) {
                    if (!snList.contains(sn)) {
                        snList.add(sn);
                    }
                }
            });
            var fullList = dao.findBySNArray(snList.toArray(new String[snList.size()]));
            return Tl.toTreeList(fullList, null);
        }
        return null;
    }

    @Override
    public Map<String, Object> getAllOrgMap() {
        var obj = new HashMap<String,Object>();
        var orgList = dao.queryAll();
        if(orgList.size()>0) {
            for (int i = 0; i < orgList.size(); i++) {
                var org = orgList.get(i);
                if (!obj.containsKey(org.getSn())) {
                    obj.put(org.getSn(), org.getFullName());
                }
            }
        }
        return obj;
    }

    @Override
    public boolean checkOrgIsEmpty(){
        return dao.queryAll().size()>0;
    }

    @Override
    public OrganizationInfoEntity findRootUnit() {
        return dao.findRootUnit();
    }

    @Override
    public int createRootInit(String orgName) throws InvocationTargetException, IllegalAccessException {
        OrganizationInfoEntity org = dao.findRootUnit();
        var result = 0;
        if(org==null) {
            org = new OrganizationInfoEntity();
            org.setFullName(orgName);
            org.setSn(queryNewSN(org.getClass()));
            org.setEnCode(HanYuHelper.getShortSpec(orgName));
            org.setParent(null);
            org.setOrganizationType(OrganizationUnitType.Company.code);
            org.setState(DataState.ENABLED.code);
            org.setPYFieldValue();
            org.setProduction(true);
            result = dao.insertNew(org);
            if (result > 0) {
                var root = userInfoDao.findBySN("USER210429000001");
                if(root!=null){
                    root.setCompanySN(org.getSn());
                    root.setOrganizationCode(org.getSn());
                    userInfoDao.update(root);
                }
                writeLog(ActionType.CREATE, org.getSn(), "插入组织架构信息信息", Tl.toJson(org), OrganizationInfoEntity.class);
            }
        }
        return result;
    }


    @Override
    public List<OrganizationInfoEntity> queryAllProductionUnits() {
       return dao.queryAllProductionUnits();
    }

    public String findUnitCodeBySN(String[] sn) {
        var unit = dao.findBySNArray(sn);
        if (unit != null && unit.size() > 0) {
            var list = new ArrayList<String>();
            unit.forEach(t -> {
                if (Tl.isEmpty(t.getParentCode())) {
                    if (!list.contains(t.getSn())) {
                        list.add(t.getSn());
                    }
                } else {
                    var s = Arrays.stream(t.getParentCode().split(",")).collect(Collectors.toList());
                    s.forEach(p -> {
                        if (!list.contains(p)) {
                            list.add(p);
                        }
                    });
                }
            });
            return String.join(",", list);
        }
        return "";
    }

    @Override
    public OrganizationInfoEntity findCompany(String[] snArray){
        return  dao.findCompany(snArray, OrganizationUnitType.Company.code);
    }

    @Override
    public OrganizationInfoEntity findBySn(String sn) {
        return dao.findBySN(sn);
    }

    @Transactional
    public Integer saveOrganizationInfo(Map<String, Object> model, String sn) throws Exception {
        Integer result = 0;
        if (Tl.isEmpty(sn)) {
            //执行保存
            OrganizationInfoEntity entity = new OrganizationInfoEntity();
            Tl.getChangeLog(entity, model);
            entity.setPYFieldValue();
            entity.setSn(queryNewSN(OrganizationInfoEntity.class));
            if (!Tl.isEmpty(entity.getParentSN())) {
                var parent = dao.findBySN(entity.getParentSN());
                if (parent != null) {
                    entity.setParent(parent);
                }
            } else {
                entity.setParentCode(entity.getSn());
            }
            result = dao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "插入组织架构信息信息", Tl.toJson(entity), OrganizationInfoEntity.class);
            }

        } else {
            //执行修改
            OrganizationInfoEntity entity = findBySn(sn);
            var backJson = entity.toJson();
            var changeLog = Tl.getChangeLog(entity, model);
            if (!Tl.isEmpty(entity.getParentSN())) {
                var parent = dao.findBySN(entity.getParentSN());
                if (parent != null) {
                    entity.setParent(parent);
                }
            }
            entity.setPYFieldValue();
            result = dao.update(entity);
            if (result > 0) {
                tagDao.updateTag(entity.getSn(), entity.getFullName());
                writeLog(ActionType.UPDATE, sn, changeLog, backJson, OrganizationInfoEntity.class);
            }
        }
        return result;
    }

    @Transactional
    public Integer delete(String[] sn) {
        var result = dao.changeStateBySn(sn, DataState.DELETED.code);
        if (result > 0) {
            tagDao.deleteTagByTagSN(sn);
            writeLog(ActionType.DELETE, sn, OrganizationInfoEntity.class);
        }
        return result;
    }
}